﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;

namespace DevCore.Utility
{
    /// <summary>
    /// 字符串辅助类
    /// </summary>
    public class StringHelper
    {

        /// <summary>
        /// 判断字符串是否是Email
        /// </summary>
        /// <param name="email"></param>
        /// <returns></returns>
        public static Boolean StrIsEmail(String email)
        {
            return Regex.IsMatch(email, @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$");

        }
        /// <summary>
        /// 验证手机号
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static bool IsMobile(string source)
        {
            return Regex.IsMatch(source, @"^1[35]\d{9}$", RegexOptions.IgnoreCase);
        }

        #region 验证是否是身份证
        /// <summary>
        /// 验证身份证是否有效
        /// </summary>
        /// <param name="Id">待验证的字符串。</param>
        /// <returns></returns>
        public static bool IsIDCard(string Id)
        {
            if (Id.Length == 18)
            {
                bool check = IsIDCard18(Id);
                return check;
            }
            else if (Id.Length == 15)
            {
                bool check = IsIDCard15(Id);
                return check;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 身份证是否是18位的
        /// </summary>
        /// <param name="Id">输入字符串</param>
        /// <returns></returns>
        public static bool IsIDCard18(string Id)
        {
            long n = 0;
            if (long.TryParse(Id.Remove(17), out n) == false || n < Math.Pow(10, 16) || long.TryParse(Id.Replace('x', '0').Replace('X', '0'), out n) == false)
            {
                return false;//数字验证
            }
            string address = "11x22x35x44x53x12x23x36x45x54x13x31x37x46x61x14x32x41x50x62x15x33x42x51x63x21x34x43x52x64x65x71x81x82x91";
            if (address.IndexOf(Id.Remove(2)) == -1)
            {
                return false;//省份验证
            }
            string birth = Id.Substring(6, 8).Insert(6, "-").Insert(4, "-");
            DateTime time = new DateTime();
            if (DateTime.TryParse(birth, out time) == false)
            {
                return false;//生日验证
            }
            string[] arrVarifyCode = ("1,0,x,9,8,7,6,5,4,3,2").Split(',');
            string[] Wi = ("7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2").Split(',');
            char[] Ai = Id.Remove(17).ToCharArray();
            int sum = 0;
            for (int i = 0; i < 17; i++)
            {
                sum += int.Parse(Wi[i]) * int.Parse(Ai[i].ToString());
            }
            int y = -1;
            Math.DivRem(sum, 11, out y);
            if (arrVarifyCode[y] != Id.Substring(17, 1).ToLower())
            {
                return false;//校验码验证
            }
            return true;//符合GB11643-1999标准
        }

        /// <summary>
        /// 验证身份证是否是15位的。
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public static bool IsIDCard15(string Id)
        {
            long n = 0;
            if (long.TryParse(Id, out n) == false || n < Math.Pow(10, 14))
            {
                return false;//数字验证
            }
            string address = "11x22x35x44x53x12x23x36x45x54x13x31x37x46x61x14x32x41x50x62x15x33x42x51x63x21x34x43x52x64x65x71x81x82x91";
            if (address.IndexOf(Id.Remove(2)) == -1)
            {
                return false;//省份验证
            }
            string birth = Id.Substring(6, 6).Insert(4, "-").Insert(2, "-");
            DateTime time = new DateTime();
            if (DateTime.TryParse(birth, out time) == false)
            {
                return false;//生日验证
            }
            return true;//符合15位身份证标准
        }

        #endregion
        /// <summary>
        /// 判断对像是否是T的类型。
        /// 如果T是DateTime那么ObjectisT<DateTime>("2010-11-02");
        /// </summary>
        /// <typeparam name="T">可以是int long datetime decimal byte 等相关的类型</typeparam>
        /// <param name="inObject"></param>
        /// <returns></returns>
        public static Boolean ObjectIsT<T>(object inObject)
        {
            Boolean isTrue = false;
            ObjectParse<T>(inObject, out isTrue);
            return isTrue;
        }

        /// <summary>
        /// 得到Guid
        /// </summary>
        /// <returns></returns>
        public static String GetGuid()
        {
            return Guid.NewGuid().ToString();
        }

        /// <summary>
        /// 为一个字符串加上两个引号
        /// </summary>
        /// <param name="inStr"></param>
        /// <returns></returns>
        public static  String AddQuotes(String inStr)
        {
            return "'" + inStr + "'";
        }

        /// <summary>
        /// 产生以日期及随机数构成的字符串。
        /// </summary>
        /// <param name="Num"></param>
        /// <returns></returns>
        public static string sRndNum(int Num)
        {
            string sTmp_Str = System.DateTime.Today.Year.ToString() + System.DateTime.Today.Month.ToString("00") + System.DateTime.Today.Day.ToString("00") + System.DateTime.Now.Hour.ToString("00") + System.DateTime.Now.Minute.ToString("00") + System.DateTime.Now.Second.ToString("00");
            return sTmp_Str + RndNum(Num);
        }


        /// <summary>
        /// 生成0-9随机数
        /// </summary>
        /// <param name="VcodeNum">生成长度</param>
        /// <returns></returns>
        public static string RndNum(int VcodeNum)
        {
            StringBuilder sb = new StringBuilder(VcodeNum);
            Random rand = new Random();
            for (int i = 1; i < VcodeNum + 1; i++)
            {
                int t = rand.Next(9);
                sb.AppendFormat("{0}", t);
            }
            return sb.ToString();
        }

        /// <summary>
        /// 随机产生一个字符串。这个字符串的原始是由Guid来产生 。
        /// 
        /// </summary>
        /// <param name="length">产生随机数的长度。</param>
        /// <returns></returns>
        public static String RandomStr(int length)
        {
            return Guid.NewGuid().ToString().Substring(0, length);
        }

        /// <summary>
        /// 对像转换为字符串
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static String ObjectToStr(object obj)
        {
            String rValue = "";
            if (obj != null)
            {
                rValue = obj.ToString();
            }
            return rValue;
        }

        /// <summary>
        /// 判断对象是否为空.
        /// </summary>
        /// <param name="obj">要判断的对象</param>
        /// <returns></returns>
        public static bool ObjectIsEmpty(object obj)
        {
            return obj == null || obj == DBNull.Value || String.IsNullOrEmpty(obj.ToString());
        }
        #region 数据转换

        /// <summary>
        /// 转换自己需要的对象。
        /// </summary>
        /// <typeparam name="T">目标对象</typeparam>
        /// <param name="o">源对象</param>
        /// <param name="isSuccess">转换是否成功</param>
        /// <returns></returns>
        public static T ObjectParse<T>(object o, out bool isSuccess)
        {
            return ObjectParse<T>(o, default(T), out isSuccess);
        }

        /// <summary>
        /// 转换成想要的数据类型，同时具备默认值.
        /// </summary>
        /// <typeparam name="T">转换成的类型</typeparam>
        /// <param name="o">源对象</param>
        /// <param name="defaultValue">默认值</param>
        /// <returns></returns>
        public static T ObjectToT<T>(object o, T defaultValue)
        {
            bool isTran = false;
            return ObjectParse<T>(o, defaultValue, out isTran);
        }

        /// <summary>
        /// 针对对像之间的转换的泛型函数
        /// </summary>
        /// <typeparam name="T">返回的类型</typeparam>
        /// <param name="o">要进行转换的对象</param>
        /// <param name="defautValue">转换失败的默认值</param>
        /// <param name="isSuccess">转换是否成功</param>
        /// <returns></returns>
        public static T ObjectParse<T>(object o, T defautValue, out bool isSuccess)
        {
            Type t = typeof (T);
            isSuccess = true;
            try
            {
                if (ObjectIsEmpty(o))
                {
                    throw new Exception();
                }

                if(t.Equals(typeof(String)))
                {
                    return (T) (object) o.ToString();
                }
                else if(t.Equals(typeof(int)))
                {
                    return (T) (object) int.Parse(o.ToString());
                }
                else if(t.Equals(typeof(long)))
                {
                    return (T) (object) long.Parse(o.ToString());
                }
                else if(t.Equals(typeof(decimal)))
                {
                    return (T) (object) decimal.Parse(o.ToString());
                }
                else if (t.Equals(typeof(byte)))
                {
                    return (T)(object)decimal.Parse(o.ToString());
                }
                else if (t.Equals(typeof(short)))
                {
                    return (T)(object)short.Parse(o.ToString());
                }
                else if (t.Equals(typeof(Guid)))
                {
                    return (T)(object)(new Guid(o.ToString()));
                }
                else if (t.Equals(typeof(DateTime)))
                {
                    return (T)(object)DateTime.Parse(o.ToString());
                }
                else if (t.Equals(typeof(bool)))
                {
                    //加入特殊判断0 与 1 是否是bool型
                    if(o.ToString() == "0")
                    {
                        return (T) (object) false;
                    }
                    else if (o.ToString() == "1")
                    {
                        return (T) (object) true;
                    }

                    return (T) (object) bool.Parse(o.ToString());
                }
                else if (t.Equals(typeof(Boolean)))
                {
                    //加入特殊判断0 与 1 是否是bool型
                    if (o.ToString() == "0")
                    {
                        return (T)(object)false;
                    }
                    else if (o.ToString() == "1")
                    {
                        return (T)(object)true;
                    }
                    return (T)(object)Boolean.Parse(o.ToString());
                }
                else if (t.Equals(typeof(byte)))
                {
                    return (T)(object)decimal.Parse(o.ToString());
                }
                else if (t.Equals(typeof(byte)))
                {
                    return (T)(object)decimal.Parse(o.ToString());
                }

                //以上类型都不存在进行强制转换
                return (T) o;
            }
            catch (Exception ex)
            {
                //如果转换发生异常
                isSuccess = false;
                if(defautValue == null)
                {
                    return default(T);
                }
                else
                {
                    return defautValue;
                }
            }
        }
        #endregion

        /// <summary>
        /// 检测是否有Sql危险字符
        /// </summary>
        /// <param name="str">要判断字符串</param>
        /// <returns>判断结果</returns>
        public static bool IsSafeSqlString(string str)
        {
            return !Regex.IsMatch(str, @"[-|;|,|\/|\(|\)|\[|\]|\}|\{|%|@|\*|!|\']");
        }

        /// <summary>
        /// 生成指定数量的html空格符号
        /// <param name="spacesCount">指定数量的空格数</param>
        /// </summary>
        public static string GetSpacesString(int spacesCount)
        {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < spacesCount; i++)
            {
                sb.Append(" &nbsp;&nbsp;");
            }
            return sb.ToString();
        }

        /// <summary>
        /// 判断文件名是否为浏览器可以直接显示的图片文件名
        /// </summary>
        /// <param name="filename">文件名</param>
        /// <returns>是否可以直接显示</returns>
        public static bool IsImgFilename(string filename)
        {
            filename = filename.Trim();
            if (filename.EndsWith(".") || filename.IndexOf(".") == -1)
                return false;

            string extname = filename.Substring(filename.LastIndexOf(".") + 1).ToLower();
            return (extname == "jpg" || extname == "jpeg" || extname == "png" || extname == "bmp" || extname == "gif");
        }

        /// <summary>
        /// 是否为ip
        /// </summary>
        /// <param name="ip"></param>
        /// <returns></returns>
        public static bool IsIP(string ip)
        {
            return Regex.IsMatch(ip, @"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$");
        }
    }
}